/**
 * Bakalarska prace - Inteligentni budik
 * @package sleepCatcher
 * @file sleepCatcher.h
 * @author Jan Pesava - xpesav00
 * @email xpesav00@stud.fit.vutbr.cz
 * @date 24. 12. 2011
 */

#include <FSysSystemTime.h>
#include <FLocales.h>

#include "SCDatabase.h"
#include "models/SCHelpers.h"
#include "models/SCDataModification.h"

using namespace Osp::Locales;

// Inicialization Static proms
Database *SCDatabase::pDatabase = null;
DbStatement *SCDatabase::pAlarmInsertStmt = null;
DbStatement *SCDatabase::pAlarmUpdateStmt = null;
DbStatement *SCDatabase::pAlarmRepeatInsertStmt = null;
DbStatement *SCDatabase::pAlarmRepeatUpdateStmt = null;
DbStatement *SCDatabase::pSessionInsertStmt = null;
DbStatement *SCDatabase::pSessionUpdateStmt = null;
DbStatement *SCDatabase::pSampleInsertStmt = null;
DbStatement *SCDatabase::pSampleUpdateStmt = null;
ArrayList *SCDatabase::pAlarmsList = null;
ArrayList *SCDatabase::pSessionsList = null;
bool SCDatabase::reloadSessions = null;
bool SCDatabase::reloadSessionsDelete = null;
bool SCDatabase::reloadAlarms = null;
bool SCDatabase::reloadAlarmsDelete = null;
ArrayList *SCDatabase::pDataModificationList = null;

SCDatabase::SCDatabase()
{
}

SCDatabase::~SCDatabase()
{
}

result
SCDatabase::Construct()
{
	AppLog("Database initializing.");

	String DBName(L"/Home/Database/SCDatabase");

	//Create DB
	pDatabase = new Database();
	if(pDatabase->Construct(DBName, true) == E_SUCCESS)
	{
		CreateSCDatabase(pDatabase);
	} else {
		AppLog("Nepodarilo se vytvorit DB");
		return E_FAILURE;
	}

	//Set Statements
	CreateStatements();

	//Load Data
	pAlarmsList = LoadAllAlarms();
	pSessionsList = LoadAllSessions();

	//Cache
	reloadSessions = false;
	reloadSessionsDelete = false;
	reloadAlarms = false;
	reloadAlarmsDelete = false;
	pDataModificationList = new ArrayList();

	return E_SUCCESS;
}

result
SCDatabase::Destruct()
{
	delete pDatabase;
	delete pAlarmInsertStmt;
	delete pAlarmUpdateStmt;
	delete pAlarmRepeatInsertStmt;
	delete pAlarmRepeatUpdateStmt;
	delete pSessionInsertStmt;
	delete pSessionUpdateStmt;
	delete pSampleInsertStmt;
	delete pSampleUpdateStmt;

	//delete cache
	pAlarmsList->RemoveAll(true);
	pSessionsList->RemoveAll(true);
	pDataModificationList->RemoveAll(true);
	delete pAlarmsList;
	delete pSessionsList;
	delete pDataModificationList;

	AppLog("Database destructed.");

	return E_SUCCESS;
}


result
SCDatabase::CreateSCDatabase(Database *database)
{
	result r;

	//Table ALARMS
	r = pDatabase->ExecuteSql("CREATE TABLE IF NOT EXISTS alarms(\
		id INTEGER PRIMARY KEY AUTOINCREMENT, \
		alarm_time TEXT NOT NULL, \
		name TEXT NOT NULL, \
		repeat_id INTEGER NOT NULL, \
		sound TEXT NOT NULL, \
		sound_level INTEGER NOT NULL, \
		awake_type INTEGER NOT NULL, \
		active INTEGER NOT NULL \
		)", true);
	if(r != E_SUCCESS)
		AppLog("Table alarms neni vytvorena.");


	//Table ALARM_REPEAT
	r = pDatabase->ExecuteSql("CREATE TABLE IF NOT EXISTS alarm_repeats(\
		id INTEGER PRIMARY KEY AUTOINCREMENT, \
		monday INTEGER NOT NULL, \
		tuesday INTEGER NOT NULL, \
		wednesday INTEGER NOT NULL, \
		thursday INTEGER NOT NULL, \
		friday INTEGER NOT NULL, \
		saturday INTEGER NOT NULL, \
		sunday INTEGER NOT NULL \
		)", true);
	if(r != E_SUCCESS)
		AppLog("Table settings neni vytvorena.");


	//Table SESSIONS
	r = pDatabase->ExecuteSql("CREATE TABLE IF NOT EXISTS sessions(\
		id INTEGER PRIMARY KEY AUTOINCREMENT, \
		start_date TEXT NOT NULL, \
		end_date TEXT NOT NULL, \
		stop_date TEXT NOT NULL, \
		quality_of_sleep INTEGER NOT NULL, \
		samples_count INTEGER NOT NULL \
		)", true);
	if(r != E_SUCCESS)
		AppLog("Table sessions neni vytvorena.");


	//Table SAMPLES
	r = pDatabase->ExecuteSql("CREATE TABLE IF NOT EXISTS samples(\
		id INTEGER PRIMARY KEY AUTOINCREMENT, \
		session_id INTEGER NOT NULL, \
		time TEXT NOT NULL, \
		type INTEGER NOT NULL, \
		energy FLOAT NOT NULL, \
		x_axis FLOAT NOT NULL, \
		y_axis FLOAT NOT NULL, \
		z_axis FLOAT NOT NULL, \
		sound_value FLOAT NOT NULL \
		)", true);
	if(r != E_SUCCESS)
		AppLog("Table samples neni vytvorena.");

	return E_SUCCESS;
}

void
SCDatabase::CreateStatements()
{
	String alarmInsertStmtStr(L"INSERT INTO alarms (id, repeat_id, alarm_time, name, sound, sound_level, awake_type, active)\
			VALUES (?, ?, ?, ?, ?, ?, ?, ?)");
	String alarmUpdateStmtStr(L"UPDATE alarms SET repeat_id = ?, alarm_time = ?, name = ?, sound = ?,\
			sound_level = ?, awake_type = ?,  active = ? WHERE id = ?");
	String alarmRepeatInsertStmtStr(L"INSERT INTO alarm_repeats (id, monday, tuesday, wednesday, thursday, friday, saturday, sunday)\
			VALUES (?, ?, ?, ?, ?, ?, ?, ?)");
	String alarmRepeatUpdateStmtStr(L"UPDATE alarm_repeats SET monday = ?, tuesday = ?, wednesday= ?, thursday = ?,\
			friday = ?, saturday = ?,  sunday = ? WHERE id = ?");
	String sessionInsertStmtStr(L"INSERT INTO sessions (id, start_date, end_date, stop_date, quality_of_sleep, samples_count)\
			VALUES (?, ?, ?, ?, ?, ?)");
	String sessionUpdateStmtStr(L"UPDATE sessions SET start_date = ?, end_date = ?, stop_date= ?, quality_of_sleep = ?, samples_count = ?\
			WHERE id = ?");
	String sampleInsertStmtStr(L"INSERT INTO samples (id, session_id, time, type, energy, x_axis, y_axis, z_axis, sound_value)\
			VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)");
	String sampleUpdateStmtStr(L"UPDATE samples SET session_id = ?, time = ?, type= ?, energy = ?,\
			x_axis = ?, y_axis = ?,  z_axis = ?, sound_value = ? WHERE id = ?");

	// Create statements
	pAlarmInsertStmt = pDatabase->CreateStatementN(alarmInsertStmtStr);
	pAlarmUpdateStmt = pDatabase->CreateStatementN(alarmUpdateStmtStr);
	pAlarmRepeatInsertStmt = pDatabase->CreateStatementN(alarmRepeatInsertStmtStr);
	pAlarmRepeatUpdateStmt = pDatabase->CreateStatementN(alarmRepeatUpdateStmtStr);
	pSessionInsertStmt = pDatabase->CreateStatementN(sessionInsertStmtStr);
	pSessionUpdateStmt = pDatabase->CreateStatementN(sessionUpdateStmtStr);
	pSampleInsertStmt = pDatabase->CreateStatementN(sampleInsertStmtStr);
	pSampleUpdateStmt = pDatabase->CreateStatementN(sampleUpdateStmtStr);
}

ArrayList*
SCDatabase::GetAllAlarms()
{
	return pAlarmsList;
}

bool
SCDatabase::SaveAlarm(SCAlarm *pAlarm)
{
	DbEnumerator* pEnum;

	// transaction start
	pDatabase->BeginTransaction();

	//Bind values
	if(pAlarm->GetId() == SCAlarm::NEW_OBJECT) //save new
	{
		pAlarmInsertStmt->BindNull(0);
		pAlarmInsertStmt->BindInt(1, pAlarm->GetAlarmRepeat()->GetId());
		pAlarmInsertStmt->BindDateTime(2, pAlarm->GetTime());
		pAlarmInsertStmt->BindString(3, pAlarm->GetName());
		pAlarmInsertStmt->BindString(4, pAlarm->GetAwakeSound());
		pAlarmInsertStmt->BindInt(5, pAlarm->GetSoundLevel());
		pAlarmInsertStmt->BindInt(6, pAlarm->GetAwakeType());
		pAlarmInsertStmt->BindInt(7, pAlarm->GetActive());

		pEnum = pDatabase->ExecuteStatementN(*pAlarmInsertStmt);

	} else { //update alarm
		pAlarmUpdateStmt->BindInt(0, pAlarm->GetAlarmRepeat()->GetId());
		pAlarmUpdateStmt->BindDateTime(1, pAlarm->GetTime());
		pAlarmUpdateStmt->BindString(2, pAlarm->GetName());
		pAlarmUpdateStmt->BindString(3, pAlarm->GetAwakeSound());
		pAlarmUpdateStmt->BindInt(4, pAlarm->GetSoundLevel());
		pAlarmUpdateStmt->BindInt(5, pAlarm->GetAwakeType());
		pAlarmUpdateStmt->BindInt(6, pAlarm->GetActive());
		pAlarmUpdateStmt->BindInt(7, pAlarm->GetId());

		pEnum = pDatabase->ExecuteStatementN(*pAlarmUpdateStmt);
	}

	//transaction end
	pDatabase->CommitTransaction();

	delete pEnum;

	//ziskani id
	if(pAlarm->GetId() == SCAlarm::NEW_OBJECT) //save new
	{
		pAlarm->SetId(GetLastInsertId("alarms"));
	}

	return true;
}


bool
SCDatabase::LoadAlarm(SCAlarm *pAlarm)
{
	if((pAlarm != NULL) && (pAlarm->GetId() != SCAlarm::NEW_OBJECT))
	{
		String statementSelect;
		DbEnumerator* pEnum;
		statementSelect.Format(1024, L"SELECT a.id, a.repeat_id, a.alarm_time, a.name, a.sound, a.sound_level, a.awake_type, a.active \
								FROM alarms a WHERE id = %i", pAlarm->GetId());

		pEnum = pDatabase->QueryN(statementSelect);

		if(pEnum != NULL)
		{
			SCAlarmRepeat* pAlarmRepeat;
			String name, sound;
			int soundLevel, awakeType, id, active, repeatId;
			DateTime time;
			while(pEnum->MoveNext() == E_SUCCESS)
			{
				pEnum->GetIntAt(0, id);
				pEnum->GetIntAt(1, repeatId);
				pEnum->GetDateTimeAt(2, time);
				pEnum->GetStringAt(3, name);
				pEnum->GetStringAt(4, sound);
				pEnum->GetIntAt(5, soundLevel);
				pEnum->GetIntAt(6, awakeType);
				pEnum->GetIntAt(7, active);

				pAlarmRepeat = new SCAlarmRepeat(repeatId);
				pAlarmRepeat->Load();
				pAlarm->SetAlarmRepeat(pAlarmRepeat);
				pAlarm->SetTime(time);
				pAlarm->SetName(name);
				pAlarm->SetAwakeSound(sound);
				pAlarm->SetSoundLevel(soundLevel);
				pAlarm->SetActive(active);
				pAlarm->SetAwakeType(awakeType);
			}

		} else {
			AppLog("Chyba Databaze.");
			return false;
		}

		delete pEnum;


	} else {
		AppLog("Objekt nema Id.");
		return false;
	}

	return true;
}


ArrayList*
SCDatabase::LoadAllAlarms()
{
	ArrayList *alarmList = new ArrayList();
	alarmList->Construct();
	String statementSelect;
	DbEnumerator* pEnum;
	SCAlarm *pAlarm;
	int id = 0;

	statementSelect.Append(L"SELECT a.id FROM alarms a");
	pEnum = pDatabase->QueryN(statementSelect);

	if(pEnum != NULL)
	{
		while(pEnum->MoveNext() == E_SUCCESS)
		{
			pEnum->GetIntAt(0, id);
			pAlarm = new SCAlarm(id);
			pAlarm->Load();
			alarmList->Add(*pAlarm);
		}
	}

	//Dealloc
	delete pEnum;

	return alarmList;
}

SCAlarm*
SCDatabase::GetAlarm(int id)
{
	IEnumerator* pEnum = pAlarmsList->GetEnumeratorN();
	SCAlarm* pAlarm = NULL;

	while(pEnum->MoveNext() == E_SUCCESS)
	{
		pAlarm = static_cast<SCAlarm*>(pEnum->GetCurrent());

		if(pAlarm->GetId() == id)
			break;
	}

	//Dealloc
	delete pEnum;

	return pAlarm;
}

SCAlarm*
SCDatabase::GetFirstActiveAlarm()
{
	DateTime currentTime, alarmTime;
	long long alarmDifference, alarmDifferenceTmp;
	SCAlarm *pAlarmCurrent = NULL, *pAlarmActive = NULL;

	if(pAlarmsList->GetCount() > 0)
	{
		// Get Current Time
		Osp::System::SystemTime::GetCurrentTime(Osp::System::WALL_TIME, currentTime);

		// Set Calendar
		String timeZoneName(L"Europe/Prague");
		TimeZone timeZone(60, timeZoneName);
		Calendar *pCalendar = Calendar::CreateInstanceN(timeZone, CALENDAR_GREGORIAN);
		pCalendar->SetTime(currentTime);
		int currentDayOfWeek = pCalendar->GetTimeField(TIME_FIELD_DAY_OF_WEEK);

		for(int i = 0; i < pAlarmsList->GetCount(); i++)
		{
			pAlarmCurrent = static_cast<SCAlarm*>(pAlarmsList->GetAt(i));

			if(pAlarmCurrent->GetActive())
			{
				alarmTime = pAlarmCurrent->GetTime();

				alarmDifferenceTmp = SCHelpers::GetTimeDifference(currentTime, alarmTime);

				if(pAlarmActive == NULL ||
						(alarmDifferenceTmp < alarmDifference))
				{
					if(currentTime.GetTimeOfDay() < alarmTime.GetTimeOfDay())
					{
						if(pAlarmCurrent->IsActiveDay(currentDayOfWeek) || pAlarmCurrent->GetAlarmRepeat()->IsJustOnlyOnce())
						{
							alarmDifference = alarmDifferenceTmp;
							pAlarmActive = pAlarmCurrent;
						}
					} else {
						if(pAlarmCurrent->IsActiveDay((currentDayOfWeek % 7) + 1) || pAlarmCurrent->GetAlarmRepeat()->IsJustOnlyOnce())
						{
							alarmDifference = alarmDifferenceTmp;
							pAlarmActive = pAlarmCurrent;
						}
					}
				}
			}
		}

		delete pCalendar;
	}

	return pAlarmActive;
}

void
SCDatabase::DeleteAlarm(int id)
{
	String statementDelete;
	statementDelete.Format(1024, L"DELETE FROM alarms WHERE id = %i", id);
	if(!pDatabase->ExecuteSql(statementDelete, true) == E_SUCCESS)
	{
		AppLog("Alarm is not deleted.");
	}
}

bool
SCDatabase::SaveAlarmRepeat(SCAlarmRepeat *pAlarmRepeat)
{
	DbEnumerator* pEnum;

	pDatabase->BeginTransaction();

	if(pAlarmRepeat->GetId() == SCAlarmRepeat::NEW_OBJECT)
	{
		pAlarmRepeatInsertStmt->BindNull(0);
		pAlarmRepeatInsertStmt->BindInt(1, pAlarmRepeat->GetMonday());
		pAlarmRepeatInsertStmt->BindInt(2, pAlarmRepeat->GetTuesday());
		pAlarmRepeatInsertStmt->BindInt(3, pAlarmRepeat->GetWednesday());
		pAlarmRepeatInsertStmt->BindInt(4, pAlarmRepeat->GetThursday());
		pAlarmRepeatInsertStmt->BindInt(5, pAlarmRepeat->GetFriday());
		pAlarmRepeatInsertStmt->BindInt(6, pAlarmRepeat->GetSaturday());
		pAlarmRepeatInsertStmt->BindInt(7, pAlarmRepeat->GetSunday());

		pEnum = pDatabase->ExecuteStatementN(*pAlarmRepeatInsertStmt);
	} else {
		pAlarmRepeatUpdateStmt->BindInt(0, pAlarmRepeat->GetMonday());
		pAlarmRepeatUpdateStmt->BindInt(1, pAlarmRepeat->GetTuesday());
		pAlarmRepeatUpdateStmt->BindInt(2, pAlarmRepeat->GetWednesday());
		pAlarmRepeatUpdateStmt->BindInt(3, pAlarmRepeat->GetThursday());
		pAlarmRepeatUpdateStmt->BindInt(4, pAlarmRepeat->GetFriday());
		pAlarmRepeatUpdateStmt->BindInt(5, pAlarmRepeat->GetSaturday());
		pAlarmRepeatUpdateStmt->BindInt(6, pAlarmRepeat->GetSunday());
		pAlarmRepeatUpdateStmt->BindInt(7, pAlarmRepeat->GetId());

		pEnum = pDatabase->ExecuteStatementN(*pAlarmRepeatUpdateStmt);
	}

	delete pEnum;

	if(pDatabase->CommitTransaction() != E_SUCCESS)
	{
		return false;
	}

	//ziskani id
	if(pAlarmRepeat->GetId() == SCAlarmRepeat::NEW_OBJECT)
	{
		pAlarmRepeat->SetId(GetLastInsertId("alarm_repeats"));
	}

	return true;
}


bool
SCDatabase::LoadAlarmRepeat(SCAlarmRepeat *pAlarmRepeat)
{
	if(pAlarmRepeat != NULL || pAlarmRepeat->GetId() != SCAlarmRepeat::NEW_OBJECT)
	{
		int monday, tuesday, wednesday, thursday, friday, saturday, sunday;
		DbEnumerator* pEnum;
		String statementSelect;
		statementSelect.Format(1024, L"SELECT ar.monday, ar.tuesday, ar.wednesday, ar.thursday, ar.friday, ar.saturday, ar.sunday  \
					FROM alarm_repeats ar WHERE id = %i", pAlarmRepeat->GetId());

		pEnum = pDatabase->QueryN(statementSelect);

		if(pEnum != NULL)
		{
			while(pEnum->MoveNext() == E_SUCCESS)
			{
				pEnum->GetIntAt(0, monday);
				pEnum->GetIntAt(1, tuesday);
				pEnum->GetIntAt(2, wednesday);
				pEnum->GetIntAt(3, thursday);
				pEnum->GetIntAt(4, friday);
				pEnum->GetIntAt(5, saturday);
				pEnum->GetIntAt(6, sunday);
			}

			pAlarmRepeat->SetMonday(monday);
			pAlarmRepeat->SetTuesday(tuesday);
			pAlarmRepeat->SetWednesday(wednesday);
			pAlarmRepeat->SetThursday(thursday);
			pAlarmRepeat->SetFriday(friday);
			pAlarmRepeat->SetSaturday(saturday);
			pAlarmRepeat->SetSunday(sunday);

			delete pEnum;
		} else {
			AppLog("Alarm repeat nenalezeno.");
		}

	} else {
		AppLog("Neni nastaveno id.");
		return false;
	}


	return true;
}


void
SCDatabase::DeleteAlarmRepeat(int id)
{
	String statementDelete;
	statementDelete.Format(1024, L"DELETE FROM alarm_repeats WHERE id = %i", id);
	if(!pDatabase->ExecuteSql(statementDelete, true) == E_SUCCESS)
	{
		AppLog("NOT DELETED.");
	}
}


bool
SCDatabase::SaveSession(SCSession *pSession)
{
	DbEnumerator* pEnum;

	pDatabase->BeginTransaction();

	if(pSession->GetId() == SCSession::NEW_OBJECT)
	{
		pSessionInsertStmt->BindNull(0);
		pSessionInsertStmt->BindDateTime(1, pSession->GetStartDate());
		pSessionInsertStmt->BindDateTime(2, pSession->GetEndDate());
		pSessionInsertStmt->BindDateTime(3, pSession->GetStopDate());
		pSessionInsertStmt->BindInt(4, pSession->GetQualityOfSleep());
		pSessionInsertStmt->BindInt(5, pSession->GetSamplesCount());

		pEnum = pDatabase->ExecuteStatementN(*pSessionInsertStmt);
	} else {
		pSessionUpdateStmt->BindDateTime(0, pSession->GetStartDate());
		pSessionUpdateStmt->BindDateTime(1, pSession->GetEndDate());
		pSessionUpdateStmt->BindDateTime(2, pSession->GetStopDate());
		pSessionUpdateStmt->BindInt(3, pSession->GetQualityOfSleep());
		pSessionUpdateStmt->BindInt(4, pSession->GetSamplesCount());
		pSessionUpdateStmt->BindInt(5, pSession->GetId());

		pEnum = pDatabase->ExecuteStatementN(*pSessionUpdateStmt);
	}

	delete pEnum;

	if(pDatabase->CommitTransaction() != E_SUCCESS)
	{
		return false;
	}

	//ziskani id
	if(pSession->GetId() == SCSample::NEW_OBJECT)
	{
		pSession->SetId(GetLastInsertId("sessions"));
	}

	return true;
}


bool
SCDatabase::LoadSession(SCSession *pSession)
{
	if(pSession != NULL || pSession->GetId() != SCAlarmRepeat::NEW_OBJECT)
	{
		int qualityOfSleep, samplesCount;
		DateTime startDate, endDate, stopDate;
		DbEnumerator* pEnum;
		String statementSelect;
		statementSelect.Format(1024, L"SELECT s.start_date, s.end_date, s.stop_date, s.quality_of_sleep, s.samples_count  \
					FROM sessions s WHERE id = %i", pSession->GetId());

		pEnum = pDatabase->QueryN(statementSelect);

		if(pEnum != NULL)
		{
			while(pEnum->MoveNext() == E_SUCCESS)
			{
				pEnum->GetDateTimeAt(0, startDate);
				pEnum->GetDateTimeAt(1, endDate);
				pEnum->GetDateTimeAt(2, stopDate);
				pEnum->GetIntAt(3, qualityOfSleep);
				pEnum->GetIntAt(4, samplesCount);

			}

			pSession->SetStartDate(startDate);
			pSession->SetEndDate(endDate);
			pSession->SetStopDate(stopDate);
			pSession->SetQualityOfSleep(qualityOfSleep);
			pSession->SetSamplesCount(samplesCount);

			delete pEnum;
		}

	} else {
		AppLog("Neni nastaveno id.");
		return false;
	}

	return true;
}

ArrayList*
SCDatabase::GetAllSessions()
{
	return pSessionsList;
}

SCSession*
SCDatabase::GetSession(int id)
{
	IEnumerator* pEnum = pSessionsList->GetEnumeratorN();
	SCSession* pSession = NULL;

	while(pEnum->MoveNext() == E_SUCCESS)
	{
		pSession = static_cast<SCSession*>(pEnum->GetCurrent());

		if(pSession->GetId() == id)
			break;
	}

	//Dealloc
	delete pEnum;

	return pSession;
}


ArrayList*
SCDatabase::LoadAllSessions()
{
	String statementSelect;
	ArrayList* pList;
	SCSession* pSession;
	int id;
	DbEnumerator* pEnum;
	statementSelect.Append(L"SELECT id FROM sessions");

	pEnum = pDatabase->QueryN(statementSelect);
	pList = new ArrayList();

	if(pEnum != NULL)
	{
		while(pEnum->MoveNext() == E_SUCCESS)
		{
			pEnum->GetIntAt(0, id);
			pSession = new SCSession(id);
			pSession->Load();
			pList->Add(*pSession);
		}
	}

	//Dealloc
	delete pEnum;

	return pList;
}


void
SCDatabase::DeleteSession(int id)
{
	String statementDelete;
	statementDelete.Format(1024, L"DELETE FROM sessions WHERE id = %i", id);
	if(!pDatabase->ExecuteSql(statementDelete, true) == E_SUCCESS)
	{
		AppLog("NOT DELETED.");
	}
}


SCSession*
SCDatabase::GetLastSession()
{
	String statementSelect;
	SCSession *pSession;
	DbEnumerator* pEnum;
	int id;
	statementSelect.Append(L"SELECT id FROM session ORDER BY id ASC LIMIT 1");

	pEnum = pDatabase->QueryN(statementSelect);

	while(pEnum->MoveNext() == E_SUCCESS)
	{
		pEnum->GetIntAt(0, id);
		pSession = new SCSession(id);
	}

	//Dealloc
	delete pEnum;

	return pSession;
}


ArrayList*
SCDatabase::GetAllSamplesOfSession(int sessionId)
{
	String statementSelect;
	ArrayList* pList;
	SCSample* pSample;
	int id;
	DbEnumerator* pEnum;
	statementSelect.Format(1024, L"SELECT id FROM samples WHERE session_id = %i", sessionId);

	pEnum = pDatabase->QueryN(statementSelect);
	pList = new ArrayList();

	if(pEnum != NULL)
	{
		while(pEnum->MoveNext() == E_SUCCESS)
		{
			pEnum->GetIntAt(0, id);
			pSample = new SCSample(id);
			pSample->Load();
			pList->Add(*pSample);
		}

		delete pEnum;
	}

	return pList;
}


bool
SCDatabase::SaveSample(SCSample *pSample)
{
	DbEnumerator* pEnum;

	pDatabase->BeginTransaction();

	if(pSample->GetId() == SCSample::NEW_OBJECT)
	{
		pSampleInsertStmt->BindNull(0);
		pSampleInsertStmt->BindInt(1, pSample->GetSessionId());
		pSampleInsertStmt->BindDateTime(2, pSample->GetTime());
		pSampleInsertStmt->BindInt(3, pSample->GetType());
		pSampleInsertStmt->BindDouble(4, pSample->GetEnergy());
		pSampleInsertStmt->BindDouble(5, pSample->GetXaxis());
		pSampleInsertStmt->BindDouble(6, pSample->GetYaxis());
		pSampleInsertStmt->BindDouble(7, pSample->GetZaxis());
		pSampleInsertStmt->BindDouble(8, pSample->GetSoundValue());

		pEnum = pDatabase->ExecuteStatementN(*pSampleInsertStmt);
	} else {
		pSampleUpdateStmt->BindInt(0, pSample->GetSessionId());
		pSampleUpdateStmt->BindDateTime(1, pSample->GetTime());
		pSampleUpdateStmt->BindInt(2, pSample->GetType());
		pSampleUpdateStmt->BindDouble(3, pSample->GetEnergy());
		pSampleUpdateStmt->BindDouble(4, pSample->GetXaxis());
		pSampleUpdateStmt->BindDouble(5, pSample->GetYaxis());
		pSampleUpdateStmt->BindDouble(6, pSample->GetZaxis());
		pSampleUpdateStmt->BindDouble(7, pSample->GetSoundValue());
		pSampleUpdateStmt->BindInt(8, pSample->GetId());

		pEnum = pDatabase->ExecuteStatementN(*pSampleUpdateStmt);
	}

	delete pEnum;

	if(pDatabase->CommitTransaction() != E_SUCCESS)
	{
		return false;
	}

	//ziskani id
	if(pSample->GetId() == SCSample::NEW_OBJECT)
	{
		pSample->SetId(GetLastInsertId("samples"));
	}

	return true;
}


bool
SCDatabase::LoadSample(SCSample *pSample)
{
	if(pSample != NULL || pSample->GetId() != SCAlarmRepeat::NEW_OBJECT)
	{
		int sessionId, type;
		double energy, xAxis, yAxis, zAxis, soundValue;
		DateTime time;
		DbEnumerator* pEnum;
		String statementSelect;
		statementSelect.Format(1024, L"SELECT s.session_id, s.time, s.type, s.energy, s.x_axis, s.y_axis, s.z_axis, s.sound_value  \
					FROM samples s WHERE id = %i", pSample->GetId());

		pEnum = pDatabase->QueryN(statementSelect);

		while(pEnum->MoveNext() == E_SUCCESS)
		{
			pEnum->GetIntAt(0, sessionId);
			pEnum->GetDateTimeAt(1, time);
			pEnum->GetIntAt(2, type);
			pEnum->GetDoubleAt(3, energy);
			pEnum->GetDoubleAt(4, xAxis);
			pEnum->GetDoubleAt(5, yAxis);
			pEnum->GetDoubleAt(6, zAxis);
			pEnum->GetDoubleAt(7, soundValue);
		}

		pSample->SetSessionId(sessionId);
		pSample->SetTime(time);
		pSample->SetType(type);
		pSample->SetEnergy(energy);
		pSample->SetXaxis(xAxis);
		pSample->SetYaxis(yAxis);
		pSample->SetZaxis(zAxis);
		pSample->SetSoundValue(soundValue);

		delete pEnum;

	} else {
		AppLog("Neni nastaveno id.");
		return false;
	}

	return true;
}


void
SCDatabase::DeleteSample(int id)
{
	String statementDelete;
	statementDelete.Format(1024, L"DELETE FROM samples WHERE id = %i", id);
	if(!pDatabase->ExecuteSql(statementDelete, true) == E_SUCCESS)
	{
		AppLog("NOT DELETED.");
	}
}


bool
SCDatabase::LoadSettings()
{

	return true;
}

bool
SaveSettings()
{

	return true;
}


int
SCDatabase::GetLastInsertId(String tableName)
{
	String statementSelect;
	DbEnumerator* pEnum;
	int rowId = 0;
	statementSelect.Format(1024, L"SELECT id FROM %ls ORDER BY id DESC LIMIT 1", tableName.GetPointer());

	pEnum = pDatabase->QueryN(statementSelect);

	if(pEnum != NULL)
	{
		while(pEnum->MoveNext() == E_SUCCESS)
		{
			pEnum->GetIntAt(0, rowId);
		}

		delete pEnum;
	}

	return rowId;
}

bool
SCDatabase::GetReloadSessions()
{
	return reloadSessions;
}

void
SCDatabase::SetReloadSessions(bool value)
{
	reloadSessions = value;
}

bool
SCDatabase::GetReloadSessionsDelete()
{
	return reloadSessionsDelete;
}

void
SCDatabase::SetReloadSessionsDelete(bool value)
{
	reloadSessionsDelete = value;
}

bool
SCDatabase::GetReloadAlarms()
{
	return reloadAlarms;
}

void
SCDatabase::SetReloadAlarms(bool value)
{
	reloadAlarms = value;
}

bool
SCDatabase::GetReloadAlarmsDelete()
{
	return reloadAlarmsDelete;
}

void
SCDatabase::SetReloadAlarmsDelete(bool value)
{
	reloadAlarmsDelete = value;
}

ArrayList*
SCDatabase::GetDataModificationList()
{
	return pDataModificationList;
}

void
SCDatabase::AddDataModification(int operationType, RequestId formId, int itemId)
{
	SCDataModification* pDataModification = new SCDataModification();

	pDataModification->SetOperationType(operationType);
	pDataModification->SetFormId(formId);
	pDataModification->SetItemId(itemId);

	pDataModificationList->Add(*pDataModification);
}

